package com.mico.micochange.trade;

import com.alibaba.fastjson.JSONObject;
import com.mico.micochange.common.ExchangeCacheUtils;
import com.mico.micochange.common.RedisUtils;
import com.mico.micochange.exception.MicoExcepiton;
import com.mico.micochange.server.MicoThread;
import com.mico.xchange.Exchange;
import com.mico.xchange.ExchangeFactory;
import com.mico.xchange.binance.BinanceExchange;
import com.mico.xchange.binance.service.BinanceAccountService;
import com.mico.xchange.binance.service.BinanceTradeService;
import com.mico.xchange.bitstamp.BitstampAuthenticatedV2;
import com.mico.xchange.bitstamp.BitstampExchange;
import com.mico.xchange.bitstamp.dto.trade.BitstampOrder;
import com.mico.xchange.bitstamp.service.BitstampTradeServiceRaw;
import com.mico.xchange.chaoex.Chaoex;
import com.mico.xchange.chaoex.ChaoexExchange;
import com.mico.xchange.chaoex.ChaoexUtils;
import com.mico.xchange.chaoex.dto.ChaoexStringResult;
import com.mico.xchange.chaoex.dto.marketdata.ChaoexTicker;
import com.mico.xchange.chaoex.dto.trade.ChaoexLogin;
import com.mico.xchange.chaoex.service.ChaoexMarketDataServiceRaw;
import com.mico.xchange.chaoex.service.ChaoexTradeServiceRaw;
import com.mico.xchange.currency.CurrencyPair;
import com.mico.xchange.dto.Order;
import com.mico.xchange.dto.trade.LimitOrder;
import com.mico.xchange.fcoin.FCoinExchange;
import com.mico.xchange.fcoin.dto.trade.FCoinSide;
import com.mico.xchange.fcoin.service.FCoinTradeServiceRaw;
import com.mico.xchange.huobi.HuobiExchange;
import com.mico.xchange.huobi.service.HuobiAccountService;
import com.mico.xchange.huobi.service.HuobiTradeService;
import com.mico.xchange.okcoin.OkCoinExchange;
import com.mico.xchange.okcoin.dto.trade.OkCoinTradeResult;
import com.mico.xchange.okcoin.service.OkCoinTradeServiceRaw;
import org.apache.mina.core.session.IoSession;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * Created by chenst on 2018/5/6.
 */
public class PlaceLimitOrderThread extends MicoThread {
    public PlaceLimitOrderThread(IoSession session, String message) {
        super(session, message);
    }


    @Override
    public Map doHuobiChange(JSONObject json) throws Exception {

        Map<String, String> retMap = new HashMap<String, String>();
        Exchange exchange = ExchangeCacheUtils.getExchange(HuobiExchange.class.getName(), json.get("apiKey").toString(), json.get("secretKey").toString());
        HuobiTradeService tradeService = (HuobiTradeService) exchange.getTradeService();
        HuobiAccountService accountService = (HuobiAccountService) exchange.getAccountService();
        String id = accountService.getAccounts()[0].getId() + "";
        LimitOrder limitOrder = initLimitOrder(json, id);
//        tradeService.verifyOrder(limitOrder);
        String resultLimit = null;
        if ("1".equals(json.getString("hadax"))) {
            resultLimit = tradeService.placeHadaxLimitOrder(limitOrder);
        } else {
            resultLimit = tradeService.placeLimitOrder(limitOrder);
        }
        retMap.put("result", resultLimit);
        return retMap;
    }

    @Override
    public Map doBinanceChange(JSONObject json) throws Exception {
        Exchange exchange = ExchangeCacheUtils.getExchange(BinanceExchange.class.getName(), json.get("apiKey").toString(), json.get("secretKey").toString());
        BinanceTradeService tradeService = (BinanceTradeService) exchange.getTradeService();
        BinanceAccountService accountService = (BinanceAccountService) exchange.getAccountService();
        String id = accountService.getAccountInfo().getWallet().getId();

        //币安下单originalAmount传交易币的数量，火币传交易金额
        LimitOrder limitOrder = initLimitOrder(json, id);
//        tradeService.verifyOrder(limitOrder);
        Map<String, String> retMap = new HashMap<String, String>();
        String resultLimit = tradeService.placeLimitOrder(limitOrder);
        retMap.put("result", resultLimit);
        return retMap;
    }

    @Override
    public Map doChaoexChange(JSONObject json) throws Exception {
        Exchange exchange = ExchangeFactory.INSTANCE.createExchange(ChaoexExchange.class.getName(), json.get("apiKey").toString(), json.get("secretKey").toString());
        ChaoexLogin chaoexLogin = ChaoexUtils.getToken(json.get("apiKey").toString(), json.get("secretKey").toString(), json.get("loginPwd").toString());
        ChaoexTradeServiceRaw chaoexTradeServiceRaw = (ChaoexTradeServiceRaw) exchange.getTradeService();

        //初始化数据
        String orderType = json.get("orderType").toString();
        BigDecimal originalAmount = json.getBigDecimal("originalAmount");//交易币的数量
        String baseSymbol = json.get("baseSymbol").toString();
        String counterSymbol = json.get("counterSymbol").toString();
        BigDecimal limitPrice = json.getBigDecimal("limitPrice");




        /*if(orderType.equals("00")){
            originalAmount = new BigDecimal(1);//交易币的数量
            baseSymbol = "EOS";
            counterSymbol = "CODE";
            limitPrice = new BigDecimal(1);//交易币的数量
        }else{
            originalAmount = new BigDecimal(1);//交易币的数量
            baseSymbol = "EOS";
            counterSymbol = "CODE";
            limitPrice = new BigDecimal(100000);//交易币的数量
        }*/

        /*BigDecimal price = RedisUtils.getTicketPrice(json.getString("exchange"),json.getString("counterSymbol"),json.getString("baseSymbol"));
        if (orderType.equals("00") && limitPrice.compareTo(price.multiply(new BigDecimal(1.2))) > 0) {
            throw new Exception("买入：委托价格高于市场20%暂不接受委托！");
        }

        if (!orderType.equals("00") && limitPrice.compareTo(price.multiply(new BigDecimal(0.8))) <0) {
            throw new Exception("卖出：委托价格低于市场20%暂不接受委托！");
        }*/
        ChaoexStringResult result = chaoexTradeServiceRaw.newOrder("00".equals(orderType) ? "1" : "2", ChaoexUtils.getCurrency(baseSymbol), ChaoexUtils.getCurrency(counterSymbol), originalAmount, limitPrice, chaoexLogin.getUid(), chaoexLogin.getToken());

        //防止token超时
        if ("9999".equals(result.getStatus())) {
            chaoexLogin = ChaoexUtils.getNewToken(json.get("apiKey").toString(), json.get("secretKey").toString(), json.get("loginPwd").toString());
            result = chaoexTradeServiceRaw.newOrder("00".equals(orderType) ? "1" : "2", ChaoexUtils.getCurrency(baseSymbol), ChaoexUtils.getCurrency(counterSymbol), originalAmount, limitPrice, chaoexLogin.getUid(), chaoexLogin.getToken());
        } else if (!result.isSuccess()) {
            throw new Exception(result.getError());
        }

        Map<String, String> retMap = new HashMap<String, String>();

        retMap.put("result", result.getResult());
        return retMap;
    }

    @Override
    public Map doBitstampChange(JSONObject json) throws Exception {
        //初始化数据
        String orderType = json.get("orderType").toString();
        BigDecimal originalAmount = json.getBigDecimal("originalAmount");//交易币的数量
        String baseSymbol = json.get("baseSymbol").toString();
        String counterSymbol = json.get("counterSymbol").toString();
        BigDecimal limitPrice = json.getBigDecimal("limitPrice");
        CurrencyPair currencyPair = new CurrencyPair(baseSymbol, counterSymbol);
        BitstampAuthenticatedV2.Side side = "00".equals(orderType) ? BitstampAuthenticatedV2.Side.buy : BitstampAuthenticatedV2.Side.sell;

        Exchange exchange = ExchangeFactory.INSTANCE.createExchange(BitstampExchange.class.getName(), json.get("apiKey").toString(), json.get("secretKey").toString());
        BitstampTradeServiceRaw tradeService = (BitstampTradeServiceRaw) exchange.getTradeService();
        BitstampOrder order = tradeService.placeBitstampOrder(currencyPair, side, originalAmount, limitPrice);
        String orderId = "" + order.getId();
        Map<String, String> retMap = new HashMap<String, String>();

        retMap.put("result", orderId);
        return retMap;

    }

    @Override
    public Map doOkexChange(JSONObject json) throws Exception {
        //初始化数据
        String orderType = json.get("orderType").toString();
        BigDecimal originalAmount = json.getBigDecimal("originalAmount");//交易币的数量
        String baseSymbol = json.get("baseSymbol").toString();
        String counterSymbol = json.get("counterSymbol").toString();
        BigDecimal limitPrice = json.getBigDecimal("limitPrice");
        String symbol = counterSymbol.toLowerCase() + "_" + baseSymbol.toLowerCase();
        String tradeType = orderType.equals("00") ? "buy" : "sell";

        //现货交易
        Exchange exchange = ExchangeFactory.INSTANCE.createExchange(OkCoinExchange.class.getName(), json.get("apiKey").toString(), json.get("secretKey").toString());
        OkCoinTradeServiceRaw okCoinTradeServiceRaw = (OkCoinTradeServiceRaw) exchange.getTradeService();
        OkCoinTradeResult result = okCoinTradeServiceRaw.trade(symbol, tradeType, limitPrice.toPlainString(), originalAmount.toPlainString());
        if (result.isResult()) {
            Map<String, String> retMap = new HashMap<String, String>();
            retMap.put("result", result.getOrderId() + "");
            return retMap;
        }
        return null;
    }

    @Override
    public Map doFCoinExchange(JSONObject json) throws Exception {
        //初始化数据

        BigDecimal limitPrice = json.getBigDecimal("limitPrice");
        BigDecimal originalAmount = json.getBigDecimal("originalAmount");//交易币的数量
        String orderType = json.get("orderType").toString();
        FCoinSide tradeType = orderType.equals("00") ? FCoinSide.buy : FCoinSide.sell;
        String baseSymbol = json.get("counterSymbol").toString();
        String counterSymbol = json.get("baseSymbol").toString();
        String symbol = counterSymbol.toLowerCase() + baseSymbol.toLowerCase();

        Exchange exchange = ExchangeFactory.INSTANCE.createExchange(FCoinExchange.class.getName(), json.get("apiKey").toString(), json.get("secretKey").toString());
        FCoinTradeServiceRaw tradeService = (FCoinTradeServiceRaw) exchange.getTradeService();
        String order_id = tradeService.placeLimitOrder(symbol, originalAmount, limitPrice, tradeType);
        Map<String, String> retMap = new HashMap<String, String>();
        retMap.put("result", order_id);
        return retMap;
    }

    private LimitOrder initLimitOrder(JSONObject json, String orderId) {
        //初始化数据
        String orderType = json.get("orderType").toString();
        BigDecimal originalAmount = json.getBigDecimal("originalAmount");//交易币的数量
        String baseSymbol = json.get("baseSymbol").toString();
        String counterSymbol = json.get("counterSymbol").toString();
        BigDecimal limitPrice = json.getBigDecimal("limitPrice");
        LimitOrder limitOrder = new LimitOrder("00".equals(orderType) ? Order.OrderType.BID : Order.OrderType.ASK, originalAmount, new CurrencyPair(baseSymbol, counterSymbol), orderId, new Date(), limitPrice);
        return limitOrder;
    }
}
